package com.sz.biz.logistics.core.service.impl;

import com.google.common.collect.Lists;
import com.sz.biz.common.constants.CommCodes;
import com.sz.biz.common.constants.ErrorCodes;
import com.sz.biz.common.constants.ModuleNames;
import com.sz.biz.logistics.constants.SubServiceTypes;
import com.sz.biz.logistics.base.entity.RegionItem;
import com.sz.biz.logistics.core.constants.ProductServiceRegionConstants;
import com.sz.biz.logistics.core.dto.*;
import com.sz.biz.logistics.core.entity.*;
import com.sz.biz.logistics.base.service.RegionItemService;
import com.sz.biz.logistics.core.service.ServiceService;
import com.sz.biz.logistics.core.service.ServiceTypeRelService;
import com.sz.biz.logistics.core.service.ProductService;
import com.sz.biz.logistics.core.service.ProductServiceCargotypeRelService;
import com.sz.biz.logistics.core.service.ProductServiceRegionRelService;
import com.sz.biz.logistics.core.service.ProductServiceRelService;
import com.sz.common.base.constants.UserActions;
import com.sz.common.base.dao.ParamData;
import com.sz.common.base.exception.Exceptions;
import com.sz.common.base.service.AbstractService;
import com.sz.common.base.utils.EntityUtils;
import com.sz.common.base.utils.StringUtils;
import com.sz.common.core.service.PrincipalLogUtils;
import com.sz.common.core.system.service.SysDictService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.*;

/**
 * Function: ProductServiceRelServiceImpl. <br>
 * Date: 2017年04月25日 14:50 <br>
 * Author: wentao.chang
 */
@org.springframework.stereotype.Service
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class ProductServiceRelServiceImpl extends AbstractService implements ProductServiceRelService {
    @Autowired
    private ProductService productService;
    @Autowired
    private ServiceService serviceService;
    @Autowired
    private ServiceTypeRelService serviceTypeRelService;
    @Autowired
    private SysDictService sysDictService;
    @Autowired
    private ProductServiceRegionRelService productServiceRegionRelService;
    @Autowired
    private RegionItemService regionItemService;
    @Autowired
    private ProductServiceCargotypeRelService productServiceCargotypeRelService;

    /**
     * 根据服务uid获取已经上线的服务
     *
     * @param uids
     * @return
     */
    @Override
    public List<ProductServiceRel> findOnlineProductByServiceUids(List<String> uids) {
        ParamData pd = new ParamData();
        pd.put("uids", uids);
        return dao.findForList(getSqlName("findOnlineProductByServiceUids"), pd, ProductServiceRel.class);
    }

    /**
     * 新增
     *
     * @param entry 新增的实体
     * @return 新增是否成功
     */
    @Override
    public Integer save(ProductServiceRelDto entry) {
        //添加参品服务
        Integer id = saveProductService(entry);
        return id;
    }

    /**
     * 修改产品服务信息
     *
     * @param productServiceRel productServiceRel
     */
    @Override
    public void update(ProductServiceRelDto productServiceRel) {
        ProductDto productDto = productService.findById(productServiceRel.getProductId());
        if (null != productDto) {
            ProductServiceRelDeleteDto productServiceRelDeleteDto = new ProductServiceRelDeleteDto();
            productServiceRelDeleteDto.setProductUid(productDto.getUid());
            List<ProductServiceRelDeleteSubDto> serviceProperties = Lists.newArrayList();
            ProductServiceRelDeleteSubDto productServiceRelDeleteSubDto = new ProductServiceRelDeleteSubDto();
            productServiceRelDeleteSubDto.setOrdinal(productServiceRel.getOrdinal());
            productServiceRelDeleteSubDto.setServiceProperty(productServiceRel.getServiceProperty().getCode());
            serviceProperties.add(productServiceRelDeleteSubDto);
            productServiceRelDeleteDto.setServiceProperties(serviceProperties);
            //删除产品服务
            delete(productServiceRelDeleteDto, false);
            //新的产品服务信息
            saveProductService(productServiceRel);
            //保存操作日志
            Map<String, Object> dataBackup = new HashMap<>();
            dataBackup.put("UPDATE_PRODUCT_SERVICE", productServiceRel);
            PrincipalLogUtils.addOperationLog(ModuleNames.BIZ,
                    ModuleNames.BIZ_PRODUCT_SERVICE,
                    UserActions.UPDATE,
                    "修改产品的服务明细",
                    dataBackup);
        }
    }

    private Integer saveProductService(ProductServiceRelDto productServiceRelDto) {
        //判断是否已经存在主服务
        ProductServiceRel productServiceRelMainExist = checkMainService(productServiceRelDto.getProductId());
        if (null != productServiceRelMainExist &&
                ProductServicePropertyEnum.MAIN.equals(productServiceRelDto.getServiceProperty()) &&
                !productServiceRelDto.getOrdinal().equals(productServiceRelMainExist.getOrdinal())) {
            throw Exceptions.bizException(ErrorCodes.ERROR_PRODUCT_SERVICE_MAIN_EXIST, "");
        }
        //同一类型的服务在产品下只能有有一个
        checkServiceTypeInProduct(productServiceRelDto.getProductId(), productServiceRelDto.getServiceTypeCode());
        //保存产品服务范围
        List<ProductServiceRelInfo> productServiceRelInfoList = productServiceRelDto.getProductServiceRelInfos();
        if (null == productServiceRelInfoList || CollectionUtils.isEmpty(productServiceRelInfoList)) {
            throw Exceptions.bizException(com.sz.biz.logistics.constants.ErrorCodes.ERROR_ARGUMENT_ILLEGAL);
        }
        for (ProductServiceRelInfo productServiceRelInfo : productServiceRelInfoList) {
            ProductServiceRel productServiceRel = new ProductServiceRel();
            BeanUtils.copyProperties(productServiceRelDto, productServiceRel);
            //判断服务是否已经在产品中存在
            ProductServiceRel productServiceRelExist = checkServiceByProductIdAndServiceUid(productServiceRelDto.getProductId(), productServiceRelInfo.getServiceUid());
            if (null != productServiceRelExist) {
                throw Exceptions.bizException(ErrorCodes.ERROR_PRODUCT_SERVICE_EXIST, productServiceRelInfo.getServiceUid());
            }
            BeanUtils.copyProperties(productServiceRelInfo, productServiceRel);
            //判断服务的重量
            Service service = serviceService.findActivedByUid(productServiceRel.getServiceUid());
            if (service != null) {
                if (productServiceRel.getWeightLimitMin() == null) {
                    productServiceRel.setWeightLimitMin(service.getWeightLimitMin());
                }
                if (productServiceRel.getWeightLimitMax() == null) {
                    productServiceRel.setWeightLimitMax(service.getWeightLimitMax());
                }
            }

            //保存产品服务信息
            dao.save(getSqlName("insert"), productServiceRel);
            //保存操作日志
            Map<String, Object> dataBackup = new HashMap<>();
            dataBackup.put("ADD_PRODUCT_SERVICE", productServiceRel);
            PrincipalLogUtils.addOperationLog(ModuleNames.BIZ,
                    ModuleNames.BIZ_PRODUCT_SERVICE,
                    UserActions.ADD,
                    "添加产品的服务明细",
                    dataBackup);
            //产品服务货物类型信息
            List<ProductServiceRelCargotypeInfo> productServiceRelCargotypeInfoList = productServiceRelInfo.getCargos();
            saveProductServiceCagotypeRel(productServiceRelCargotypeInfoList, productServiceRel.getId());
            //产品服务范围维护
            saveProductServiceRegions(productServiceRelDto, productServiceRelInfo, productServiceRel);
        }
        return null;
    }

    /**
     * 产品服务范围维护
     *
     * @param productServiceRelDto
     * @param productServiceRelInfo
     * @param productServiceRel
     */
    private void saveProductServiceRegions(ProductServiceRelDto productServiceRelDto, ProductServiceRelInfo productServiceRelInfo, ProductServiceRel productServiceRel) {
        //非干线服务
        List<Integer> notLine = Lists.newArrayList();
        //干线空运
        List<Integer> lineAir = Lists.newArrayList();
        //干线空运
        List<Integer> lineShip = Lists.newArrayList();
        //保存产品服务范围信息
        //产品服务范围开始
        //冗余一个所有分区明细
        StringBuffer itemDetail = new StringBuffer();
        List<ProductServiceRelRegionInfo> productServiceRegionIdsStart = productServiceRelInfo.getRegionsStart();
        if (null != productServiceRegionIdsStart && !CollectionUtils.isEmpty(productServiceRegionIdsStart)) {
            for (ProductServiceRelRegionInfo region : productServiceRegionIdsStart) {
                if(region == null){
                    continue;
                }
                saveProductServiceRegionRel(productServiceRel.getId(), productServiceRelDto, productServiceRelInfo, region, CommCodes.PRODUCT_SERVICE_REGION_START);
                //服务类型是否为干线
                String serviceTypeCode = productServiceRelDto.getServiceTypeCode();
                //干线服务
                if (!StringUtils.isEmpty(serviceTypeCode) && "ST004".equals(serviceTypeCode)) {
                    Service service = serviceService.findActivedByUid(productServiceRelInfo.getServiceUid());
                    if (null != service) {
                        //空运or海运
                        List<ServiceTypeRel> serviceTypeRels = serviceTypeRelService.findByRefId(service.getId());
                        if (!CollectionUtils.isEmpty(serviceTypeRels)) {
                            String serviceSubType = serviceTypeRels.get(0).getSubServiceTypeCode();
                            //空运
                            if (!StringUtils.isEmpty(serviceSubType) && SubServiceTypes.MAINLINE_AIR.equals(serviceSubType)) {
                                lineAir.add(Integer.valueOf(region.getId()));
                            } else if (!StringUtils.isEmpty(serviceSubType) && SubServiceTypes.MAINLINE_SHIP.equals(serviceSubType)) { /*海运*/
                                lineShip.add(Integer.valueOf(region.getId()));
                            } else {
                                notLine.add(Integer.valueOf(region.getId()));
                            }
                        }
                    }
                } else { //非干线服务
                    notLine.add(Integer.valueOf(region.getId()));
                }
            }

            //非干线服务范围
            if (!CollectionUtils.isEmpty(notLine)) {
                List<RegionItem> regionItems = regionItemService.findByIds(notLine);
                if (!CollectionUtils.isEmpty(regionItems)) {
                    for (RegionItem regionItem : regionItems) {
                        itemDetail.append(regionItem.getDetailString()).append("|");
                    }
                }
            }
            //空运服务
            if (!CollectionUtils.isEmpty(lineAir)) {
                for (Integer flightId : lineAir) {
                    itemDetail.append(flightId).append("|");
                }
            }
            //海运服务
            if (!CollectionUtils.isEmpty(lineShip)) {
                for (Integer shipId : lineShip) {
                    itemDetail.append(shipId).append("|");
                }
            }

        }
        //产品服务范围终点
        List<ProductServiceRelRegionInfo> productServiceRegionIdsEnd = productServiceRelInfo.getRegionsEnd();
        if (null != productServiceRegionIdsEnd && !CollectionUtils.isEmpty(productServiceRegionIdsEnd)) {
            notLine.clear();
            for (ProductServiceRelRegionInfo region : productServiceRegionIdsEnd) {
                saveProductServiceRegionRel(productServiceRel.getId(), productServiceRelDto, productServiceRelInfo, region, CommCodes.PRODUCT_SERVICE_REGION_END);
                notLine.add(Integer.valueOf(region.getId()));

            }

            //非干线服务范围
            if (!CollectionUtils.isEmpty(notLine)) {
                List<RegionItem> regionItems = regionItemService.findByIds(notLine);
                if (!CollectionUtils.isEmpty(regionItems)) {
                    itemDetail.append(ProductServiceRegionConstants.REGIONSPLIT);
                    for (RegionItem regionItem : regionItems) {
                        itemDetail.append(regionItem.getDetailString()).append("|");
                    }
                }
            }

        }


        if (!StringUtils.isEmpty(itemDetail.toString())) {
            //更新itemDetail
            updateItemDetail(productServiceRel.getId(), itemDetail.toString());
        }

    }

    private void saveProductServiceRegionRel(Integer psId, ProductServiceRelDto productServiceRelDto, ProductServiceRelInfo productServiceRelInfo, ProductServiceRelRegionInfo region, String type) {
        ProductServiceRegionRel productServiceRegionRel = new ProductServiceRegionRel();
        productServiceRegionRel.setPsId(psId);
        productServiceRegionRel.setType(type);
        productServiceRegionRel.setProductId(productServiceRelDto.getProductId());
        productServiceRegionRel.setProductUid(productServiceRelDto.getProductUid());
        productServiceRegionRel.setServiceUid(productServiceRelInfo.getServiceUid());
        productServiceRegionRel.setRegion(region.getId());
        productServiceRegionRel.setRegionName(region.getName());
        productServiceRegionRelService.save(productServiceRegionRel);
    }

    /**
     * 保存产品服务信息货物类型
     *
     * @param productServiceRelCargotypeInfoList
     * @param psId
     */
    private void saveProductServiceCagotypeRel(List<ProductServiceRelCargotypeInfo> productServiceRelCargotypeInfoList, Integer psId) {
        if (null != productServiceRelCargotypeInfoList && !CollectionUtils.isEmpty(productServiceRelCargotypeInfoList)) {
            for (ProductServiceRelCargotypeInfo cargotype : productServiceRelCargotypeInfoList) {
                ProductServiceCargotypeRel productServiceCargotypeRel = new ProductServiceCargotypeRel();
                productServiceCargotypeRel.setPsId(psId);
                productServiceCargotypeRel.setCargoTypeCode(cargotype.getCargoTypeCode());
                productServiceCargotypeRel.setCargoTypeName(cargotype.getCargoTypeName());
                productServiceCargotypeRelService.save(productServiceCargotypeRel);
            }
        }
    }

    /**
     * 冗余产品服务范围
     *
     * @param productServiceId
     * @param itemDetail
     */
    private void updateItemDetail(Integer productServiceId, String itemDetail) {
        Map<String, Object> map = new HashMap<>();
        map.put("id", productServiceId);
        map.put("itemDetail", itemDetail);
        dao.update(getSqlName("updateItemDetail"), map);
    }

    /**
     * 检索产品主服务
     *
     * @param productId
     * @return
     */
    @Override
    public ProductServiceRel checkMainService(Integer productId) {
        return (ProductServiceRel) dao.findForObject(getSqlName("checkMainService"), productId);
    }

    /**
     * 获取主服务，必选服务
     *
     * @param productId
     * @param serviceTypeCode
     * @return
     */
    @Override
    public List<String> checkMainRequiredService(Integer productId, String serviceTypeCode) {
        ParamData paramData = new ParamData();
        paramData.put("productId", productId);
        paramData.put("serviceTypeCode", serviceTypeCode);
        return dao.findForList(getSqlName("checkMainRequiredService"), paramData, String.class);
    }

    /**
     * 根据产品id和服务uid获取服务-判顿服务在产品中是否已经存在
     *
     * @param productId
     * @param serviceUid
     * @return
     */
    @Override
    public ProductServiceRel checkServiceByProductIdAndServiceUid(Integer productId, String serviceUid) {
        ParamData paramData = new ParamData();
        paramData.put("productId", productId);
        paramData.put("serviceUid", serviceUid);
        return (ProductServiceRel) dao.findForObject(getSqlName("checkServiceByProductIdAndServiceUid"), paramData);
    }

    /**
     * 同一种类型的服务在统一产品下只能有一个
     *
     * @return
     */
    @Override
    public void checkServiceTypeInProduct(Integer productId, String serviceTypeCode) {
        ParamData paramData = new ParamData();
        paramData.put("productId", productId);
        paramData.put("serviceTypeCode", serviceTypeCode);
        ProductServiceRel productServiceRel = (ProductServiceRel) dao.findForObject(getSqlName("checkServiceTypeInProduct"), paramData);
        if (null != productServiceRel) {
            throw Exceptions.bizException(ErrorCodes.ERROR_PRODUCT_SERVICE_TYPE_EXIST);
        }
    }

    /**
     * 根据产品id，产品属性获取产品服务列表
     *
     * @return
     */
    @Override
    public List<ProductServiceTypeDto> findByProductIdAndServiceProperty(Integer productId, ProductServicePropertyEnum serviceProperty) {
        List<ProductServiceTypeDto> serviceTypeDtoList = new ArrayList<>();
        ParamData paramData = new ParamData();
        paramData.put("productId", productId);
        paramData.put("serviceProperty", serviceProperty);
        serviceTypeDtoList = dao.findForList(getSqlName("findByProductIdAndServiceProperty"), paramData, ProductServiceTypeDto.class);

        Map<String, String> serviceTypeMap = sysDictService.findMapByCatalog("biz.service.type");
        for (ProductServiceTypeDto typeDto : serviceTypeDtoList) {
            if (!StringUtils.isEmpty(typeDto.getServiceTypeCode())) {
                typeDto.setServiceTypeName(serviceTypeMap.get(typeDto.getServiceTypeCode()));
            }
        }

        return serviceTypeDtoList;
    }

    /**
     * 根据产品ids，产品属性获取产品服务列表
     *
     * @param productIds
     * @param serviceProperty
     * @return
     */
    @Override
    public List<ProductServiceTypeDto> findByProductIdsAndServiceProperty(List<Integer> productIds, ProductServicePropertyEnum serviceProperty) {
        List<ProductServiceTypeDto> serviceRelShortDtos = new ArrayList<>();
        ParamData paramData = new ParamData();
        paramData.put("productIds", productIds);
        paramData.put("serviceProperty", serviceProperty);
        serviceRelShortDtos = dao.findForList(getSqlName("findByProductIdsAndServiceProperty"), paramData, ProductServiceTypeDto.class);

        Map<String, String> serviceTypeMap = sysDictService.findMapByCatalog("biz.service.type");
        for (ProductServiceTypeDto serviceRelShortDto : serviceRelShortDtos) {
            if (!StringUtils.isEmpty(serviceRelShortDto.getServiceTypeCode())) {
                serviceRelShortDto.setServiceTypeName(serviceTypeMap.get(serviceRelShortDto.getServiceTypeCode()));
            }
        }

        return serviceRelShortDtos;
    }

    /**
     * 验证揽收地址有效性
     *
     * @param uid
     * @param serviceUids
     * @param serviceType @return
     */
    @Override
    public List<ProductRegionRel> checkReceiveAddress(String uid, List<String> serviceUids, String serviceType) {
        ParamData paramData = new ParamData();
        paramData.put("uid", uid);
        paramData.put("serviceUids", serviceUids);
        paramData.put("serviceType", serviceType);
        return dao.findForList(getSqlName("checkReceiveAddress"), paramData, ProductRegionRel.class);
    }

    /**
     * 异步校验服务是否已经在产品中存在
     *
     * @param productId
     * @param serviceUid
     */
    @Override
    public void checkServiceIsExistInProduct(Integer productId, String serviceUid) {
        ProductServiceRel productServiceRel = checkServiceByProductIdAndServiceUid(productId, serviceUid);
        if (null != productServiceRel) {
            throw Exceptions.bizException(ErrorCodes.ERROR_PRODUCT_SERVICE_EXIST, productServiceRel.getServiceUid());
        }
    }

    /**
     * 批量新增
     *
     * @param list
     */
    @Override
    public void batchsave(List<ProductServiceRel> list) {
        dao.batchInsert(getSqlName("insert"), list);
        //保存操作日志
        Map<String, Object> dataBackup = new HashMap<>();
        dataBackup.put("ADD_PRODUCT_SERVICE", list);
        PrincipalLogUtils.addOperationLog(ModuleNames.BIZ,
                ModuleNames.BIZ_PRODUCT_SERVICE,
                UserActions.ADD,
                "添加产品的服务明细",
                dataBackup);
    }

    @Override
    public void save(ProductServiceRel productServiceRel) {
        dao.save(getSqlName("insert"), productServiceRel);
        //保存操作日志
        Map<String, Object> dataBackup = new HashMap<>();
        dataBackup.put("ADD_PRODUCT_SERVICE", productServiceRel);
        PrincipalLogUtils.addOperationLog(ModuleNames.BIZ,
                ModuleNames.BIZ_PRODUCT_SERVICE,
                UserActions.ADD,
                "添加产品的服务明细",
                dataBackup);
    }

    /**
     * ··
     * 根据quotationId查询单个实体
     *
     * @param productId
     * @return 查询出来的实体对象
     */
    @Override
    public List<ProductServiceRel> findByProductId(int productId) {
        ParamData pd = new ParamData();
        pd.put("productId", productId);
        return dao.findForList(getSqlName("findByProductId"), pd, ProductServiceRel.class);
    }
    /**
     * ··
     * 根据quotationId查询单个实体
     *
     * @param productId
     * @return 查询出来的实体对象
     */
    @Override
    public List<ProductServiceRel> findSimpleByProductId(int productId) {
        ParamData pd = new ParamData();
        pd.put("productId", productId);
        return dao.findForList(getSqlName("findSimpleByProductId"), pd, ProductServiceRel.class);
    }

    /**
     * 产品可选服务列表-服务类型编码+服务类型名称
     *
     * @param productId
     * @return
     */
    @Override
    public List<Map> findOptionalServiceTypes(Integer productId) {
        return dao.findForList(getSqlName("findOptionalServiceTypes"), productId, Map.class);
    }

    /**
     * 根据主键Id查询单个实体
     *
     * @param id 主键id
     * @return 查询出来的实体对象
     */
    @Override
    public ProductServiceRel findById(Integer id) {
        return (ProductServiceRel) dao.findForObject(getSqlName("findById"), id);
    }

    /**
     * 根据productId删除
     *
     * @param productId productId
     */
    @Override
    public void deleteByProductId(Integer productId) {
        dao.delete(getSqlName("deleteByProductId"), productId);
        //保存操作日志
        Map<String, Object> dataBackup = new HashMap<>();
        dataBackup.put("DELETE_PRODUCT_SERVICE", productId);
        PrincipalLogUtils.addOperationLog(ModuleNames.BIZ,
                ModuleNames.BIZ_PRODUCT_SERVICE,
                UserActions.DELETE, "删除产品服务明细", dataBackup);
    }

    @Override
    public List<ProductServiceRel> findServiceDetailsByUidAndDate(String uid, Date time, boolean hasDisabled) {
        List<ProductServiceRel> list = findServicesByUidAndDate(uid, time);
        List<String> serviceUids = EntityUtils.getStringPropListFromBeans(list, "serviceUid");
        Map<String, Service> mapService = new HashMap<>();
        List<String> onlinedServices = new ArrayList<>();
        if (!CollectionUtils.isEmpty(serviceUids)) {
            List<Service> listService = serviceService.findByUidsAndTime(serviceUids, time);
            listService.stream()
                    .filter(item -> item.getIsOnline() != null && item.getIsOnline())
                    .forEach(item -> onlinedServices.add(item.getUid()));
            mapService = EntityUtils.getStringKeyMapFromBeans(listService, "uid");
        }

        List<ProductServiceRel> listDto = new ArrayList<>();
        for (ProductServiceRel rel : list) {
            if (!hasDisabled && !onlinedServices.contains(rel.getServiceUid())
                   /* && ProductServicePropertyEnum.OPTIONAL.getCode().equals(rel.getServiceProperty().getCode())*/) {
                continue;
            }
            ProductServiceRel dto = new ProductServiceRel();
            BeanUtils.copyProperties(rel, dto);
            Service svc = mapService.get(rel.getServiceUid());
            if (svc != null) {
                dto.setIsEnable(svc.getIsOnline() == null ? false : svc.getIsOnline());
                dto.setServiceName(svc.getName());
            }
            listDto.add(dto);
        }
        return listDto;
    }

    @Override
    public List<ProductServiceRel> findServicesByUidAndDate(String uid, Date time) {
        List<ProductServiceRel> list = new ArrayList<>();
        Product product = productService.findByUidAndTime(uid, time);
        if (!ObjectUtils.isEmpty(product)) {
            ParamData pd = new ParamData();
            pd.put("productId", product.getId());
            list = dao.findForList("ProductServiceRelMapper.findByProductId", pd, ProductServiceRel.class);
        }
        return list;
    }

    @Override
    public ProductServiceRel findNextServices(String productUid, Date time, String serviceUid) {
        List<ProductServiceRel> list = findServicesByUidAndDate(productUid, time);
        int order = 0;
        if (list != null && list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                if (list.get(i).getServiceUid().equals(serviceUid)) {
                    order = i + 1;
                    break;
                }
            }
            if (order <= list.size() - 1) {
                ProductServiceRel productServiceRel = list.get(order);
                return productServiceRel;
            } else {
                return null;
            }
        } else {
            return null;
        }
    }

    /**
     * ··
     * 查询单个实体
     *
     * @param productId
     * @return 查询出来的实体对象
     */
    @Override
    public List<Map> findServicesByProductId(Integer productId) {
        return dao.findForList(getSqlName("findServicesByProductId"), productId, Map.class);
    }

    @Override
    public List<ProductServiceRel> findByProdIdAndServiceProperty(Integer productId, List<String> serviceProperties) {
        List<ProductServiceRel> productServiceRelList = new ArrayList<>();
        if (productId != null && productId > 0) {
            ParamData pd = new ParamData();
            pd.put("productId", productId);
            pd.put("serviceProperties", serviceProperties);
            productServiceRelList = dao.findForList(getSqlName("findByProdIdAndServiceProperty"), pd, ProductServiceRel.class);
        }
        return productServiceRelList;
    }

    @Override
    public List<ProductServiceRel> findByProdId(Integer productId) {
        List<ProductServiceRel> productServiceRelList = new ArrayList<>();
        if (productId != null && productId > 0) {
            productServiceRelList = this.findByProdIdAndServiceProperty(productId, null);
        }
        return productServiceRelList;
    }

    /**
     * 删除产品服务
     *
     * @param ids
     * @return
     */
    @Override
    public int batchDeleteById(List<Integer> ids) {
        ParamData paramData = new ParamData();
        paramData.put("ids", ids);
        return (int) dao.delete(getSqlName("batchDeleteById"), paramData);
    }

    @Override
    public void delete(ProductServiceRelDeleteDto productServiceRelDeleteDto, boolean deleteAll) {
        if (null != productServiceRelDeleteDto) {
            List<Integer> ids = Lists.newArrayList();
            String productUid = productServiceRelDeleteDto.getProductUid();
            List<ProductServiceRelDeleteSubDto> serviceProperties = productServiceRelDeleteDto.getServiceProperties();
            if (null != serviceProperties && !CollectionUtils.isEmpty(serviceProperties)) {
                for (ProductServiceRelDeleteSubDto serviceProperty : serviceProperties) {
                    Integer ordinal = serviceProperty.getOrdinal();
                    String servicePropertyCode = serviceProperty.getServiceProperty();
                    if (deleteAll) {
                        servicePropertyCode = "ALL";
                    }
                    //产品服务信息列表
                    List<ProductServiceRel> productServiceRelList = productService.findProductServices(productUid, servicePropertyCode.toUpperCase(), ordinal, true, false);
                    if (null != productServiceRelList && !CollectionUtils.isEmpty(productServiceRelList)) {
                        for (ProductServiceRel productServiceRel : productServiceRelList) {
                            ids.add(productServiceRel.getId());
                        }
                    }
                }
            }
            if (!CollectionUtils.isEmpty(ids)) {
                //删除产品服务
                batchDeleteById(ids);
                //删除产品服务范围
                productServiceRegionRelService.batchDeleteByPsIds(ids);
                //删除产品服务货物类型
                productServiceCargotypeRelService.batchDeleteByPsIds(ids);
            }
            //保存操作日志
            Map<String, Object> dataBackup = new HashMap<>();
            dataBackup.put("DELETE_PRODUCT_SERVICE", productServiceRelDeleteDto);
            PrincipalLogUtils.addOperationLog(ModuleNames.BIZ, ModuleNames.BIZ_PRODUCT, UserActions.DELETE, "产品服务删除(根据服务属性删除)", dataBackup);
        }
    }

    /**
     * 根据产品服务id删除服务
     *
     * @param psIds
     */
    @Override
    public void deleteByPsIds(List<Integer> psIds) {
        if (!CollectionUtils.isEmpty(psIds)) {
            //删除产品服务
            batchDeleteById(psIds);
            //删除产品服务范围
            productServiceRegionRelService.batchDeleteByPsIds(psIds);
            //删除产品服务货物类型
            productServiceCargotypeRelService.batchDeleteByPsIds(psIds);
        }
    }

    @Override
    protected String getMapperNamespace() {
        return "ProductServiceRelMapper";
    }
}
